package com.example.demo22;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
        private Button send;
        private Button send2;
        private Button send3;
        private Button send4;
        private Button send5;
        private Button send6;
        private EditText inputUrl;
        private TextView reUrlData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //注册绑定控件
        send = findViewById(R.id.send_url1);
        send2 = findViewById(R.id.send_url2);
        send3 = findViewById(R.id.send_xml);
        send4 = findViewById(R.id.send_xml2);
        send5 = findViewById(R.id.send_json1);
        send6 = findViewById(R.id.send_json2);
        inputUrl = findViewById(R.id.input_url);
        reUrlData = findViewById(R.id.re_url_data);
        //点击事件
        send.setOnClickListener(this);
        send2.setOnClickListener(this);
        send3.setOnClickListener(this);
        send4.setOnClickListener(this);
        send5.setOnClickListener(this);
        send6.setOnClickListener(this);
    }

    /**
     * 点击事件
     * @param v
     */
    @Override
    public void onClick(View v) {
        if (v.getId()==R.id.send_url1){
            sendHttpUrl();
        }

        if (v.getId()==R.id.send_url2){
            sendOkHttpUrl();
        }
        if (v.getId()==R.id.send_xml){
            getXmlAndJSON(R.id.send_xml);
        }
        if (v.getId()==R.id.send_xml2){
            getXmlAndJSON(R.id.send_xml2);
        }
        if (v.getId()==R.id.send_json1){
            getXmlAndJSON(R.id.send_json1);
        }
        if (v.getId()==R.id.send_json2){
            getXmlAndJSON(R.id.send_json2);
        }
    }

    /**
     * 获取XML或JSON文档内容
     * @param id
     */
    private void getXmlAndJSON(final int id) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String u=inputUrl.getText().toString();
                //创建OkHttp实例
                OkHttpClient client=new OkHttpClient();
                try {
                    //创建请求
                    Request request = new Request.Builder().url(u).build();
                    //发送请求返回获取的数据
                    Response response = client.newCall(request).execute();
                    //读取响应正文
                    String data = response.body().string();
                    if (id==R.id.send_xml) {
                        pullParserXML(data);
                    }else if (id==R.id.send_xml2){
                        saxParserXML(data);
                    }else if (id==R.id.send_json1){
                        parserWithJSONObject(data);
                    }else if (id==R.id.send_json2){

                    }
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }catch (IllegalArgumentException e){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),"请输入正确的网址",Toast.LENGTH_SHORT).show();
                        }
                    });
                    e.printStackTrace();
                }
            }

        }).start();
    }

    private void parserWithJSONObject(String data) {
        String error = "";
        String status = "";
        String date = "";
        String currentCity = "";
        String pm25 = "";
        List<HashMap<String,String>> indexList=new ArrayList<>();
        List<HashMap<String,String>> weatherDataList=new ArrayList<>();
        try {
            //json转换为JSON数组实例
            JSONObject jsonObject = new JSONObject(data);
            //遍历数组取出对象
            error = jsonObject.getString("error");
            status = jsonObject.getString("status");
            date = jsonObject.getString("date");
            JSONArray result = jsonObject.getJSONArray("results");
            for (int i1 = 0; i1 < result.length(); i1++) {
                JSONObject resultJSONObject = result.getJSONObject(i1);
                currentCity = resultJSONObject.getString("currentCity");
                pm25 = resultJSONObject.getString("pm25");
                JSONArray index = resultJSONObject.getJSONArray("index");
                for (int i2 = 0; i2 < index.length(); i2++) {
                    JSONObject indexJSONObject = index.getJSONObject(i2);
                    String des = indexJSONObject.getString("des");
                    String tipt = indexJSONObject.getString("tipt");
                    String title = indexJSONObject.getString("title");
                    String zs = indexJSONObject.getString("zs");
                    HashMap<String, String> map = new HashMap<>();
                    map.put("des", des);
                    map.put("tipt", tipt);
                    map.put("title", title);
                    map.put("zs", zs);
                    indexList.add(map);
                }
                JSONArray weather_data = resultJSONObject.getJSONArray("weather_data");
                for (int i2 = 0; i2 < weather_data.length(); i2++) {
                    JSONObject dataJSONObject = weather_data.getJSONObject(i2);
                    String weather_date = dataJSONObject.getString("date");
                    String dayPictureUrl = dataJSONObject.getString("dayPictureUrl");
                    String nightPictureUrl = dataJSONObject.getString("nightPictureUrl");
                    String weather = dataJSONObject.getString("weather");
                    String wind = dataJSONObject.getString("wind");
                    String temperature = dataJSONObject.getString("temperature");
                    HashMap<String, String> map = new HashMap<>();
                    map.put("weather_date", weather_date);
                    map.put("temperature", temperature);
                    map.put("wind", wind);
                    map.put("weather", weather);
                    map.put("dayPictureUrl", dayPictureUrl);
                    map.put("nightPictureUrl", nightPictureUrl);
                    weatherDataList.add(map);
                }
            }

            //组装数据
            packageWeatherData(error, status, date, currentCity, pm25, indexList, weatherDataList);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * 封装数据
     * @param error 错误数
     * @param status 获取状态
     * @param date  当前时间
     * @param currentCity 当前城市
     * @param pm25  pm2.5
     * @param indexList 未来五天建议集合
     * @param weatherDataList   未来五天天气情况
     */
    private void packageWeatherData(String error, String status, String date, String currentCity, String pm25, List<HashMap<String, String>> indexList, List<HashMap<String, String>> weatherDataList) {
        StringBuilder weather_data1=new StringBuilder();
        StringBuilder weather_data2=new StringBuilder();
        weather_data1.append("当前时间："+date+"\n当前城市："+currentCity+"\nPM2.5:"
                +pm25+"\n天气情况获取："+status+",错误："+error+"\n");
        for (int i = 0; i < weatherDataList.size(); i++) {
            HashMap<String, String> weatherData = weatherDataList.get(i);
            String weatherDate = weatherData.get("weather_date");
            String weather = weatherData.get("weather");
            String wind = weatherData.get("wind");
            String temperature = weatherData.get("temperature");
            String dayPictureUrl = weatherData.get("dayPictureUrl");
            String nightPictureUrl = weatherData.get("nightPictureUrl");
            weather_data2.append(weatherDate+": "+weather+" " +
                    wind+"  "+temperature+"\n");
            if (i==0){
                for (HashMap<String, String> weatherIndex : indexList) {
                    String title = weatherIndex.get("title");
                    String tipt = weatherIndex.get("tipt");
                    String zs = weatherIndex.get("zs");
                    String des = weatherIndex.get("des");
                    weather_data2.append("  "+tipt+":"+zs+","+des+"\n");
                }
            }
        }
        showUrlData(weather_data1.toString()+weather_data2.toString());
    }

    /**
     * sax解析XML数据
      * @param data XML文本内容
     */
    private void saxParserXML(String data) {
        //获取sax解析器工厂类
        SAXParserFactory saxParserFactory=SAXParserFactory.newInstance();
        try {
            //获取sax解析器接口
            SAXParser saxParser = saxParserFactory.newSAXParser();
            //获取解析器实例
            XMLReader xmlReader = saxParser.getXMLReader();
            MySaxHandler mySaxHandler=new MySaxHandler();
            //传入自定义的回调对象
            xmlReader.setContentHandler(mySaxHandler);
            //解析xml数据
            xmlReader.parse(new InputSource(new StringReader(data)));
            //获取解析完成的数据
            List<HashMap<String, String>> news = mySaxHandler.getNews();
            //显示解析的数据
            showUrlData(news.toString());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * Pull解析XML数据
     * @param data XML文本内容
     */
    private void pullParserXML(String data) {
        try {
            //获取pull解析工厂实例
            XmlPullParserFactory pullParserFactory = XmlPullParserFactory.newInstance();
            //获取pull解析实例
            XmlPullParser xmlPullParser = pullParserFactory.newPullParser();
            //传入xml输入字符流
            xmlPullParser.setInput(new StringReader(data));
            //获取解析事件
            int eventType = xmlPullParser.getEventType();
            String title="",content="";
            StringBuilder builder=new StringBuilder();
            //循环解析直到最后一个节点结束标签
            while (eventType != XmlPullParser.END_DOCUMENT) {
                //获取当前节点名
                String nodeName = xmlPullParser.getName();
                switch (eventType){
                    //解析某个节点
                    case XmlPullParser.START_TAG:
                        //获取节点的内容
                        if ("title".equals(nodeName)){
                            title=xmlPullParser.nextText();
                        }else if ("content".equals(nodeName)){
                            content=xmlPullParser.nextText();
                        }
                        break;
                        case XmlPullParser.END_TAG:
                            //解析完一个节点就将结果打印出来
                            if ("news".equals(nodeName)){
                                Log.d("parseXML", "title:"+title);
                                Log.d("parseXML", "content:"+content);
                                builder.append("标题:"+title+"\n      内容:"+content+"\n");
                            }
                            break;
                    default:
                        break;
                }
                //获取下一个解析事件
                eventType=xmlPullParser.next();
            }
            showUrlData(builder.toString());
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * OkHttp访问网络
     */
    private void sendOkHttpUrl() {
        new Thread(new Runnable() {
            @Override
            public void run() {

                String u=inputUrl.getText().toString();
                //创建OkHttp实例
                OkHttpClient client=new OkHttpClient();
                try {
                    //创建请求
                    Request request = new Request.Builder().url(u).build();
                    //发送请求返回获取的数据
                    Response response = client.newCall(request).execute();
                    //读取响应正文
                    String data = response.body().string();
                    showUrlData(data);
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }catch (IllegalArgumentException e){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),"请输入正确的网址",Toast.LENGTH_SHORT).show();
                        }
                    });
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * Http/https访问网络
     */
    private void sendHttpUrl() {
        Thread thread=new Thread(new Runnable() {
            @Override
            public void run() {
                String u=inputUrl.getText().toString();
                StringBuilder builder=new StringBuilder();
                InputStream inputStream = null;
                BufferedReader reader = null;
                try {
                    //创建URL对象
                    URL url=new URL(u);
                    //获取连接实例
                    URLConnection connection = url.openConnection();
                    //设置处理参数
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    //建立远程对象的实际连接
                    connection.connect();
                    //获取响应内容的头字段
                    Map<String, List<String>> headerFields = connection.getHeaderFields();
                    System.out.println(headerFields);
                    //获取输入的正文内容
                    inputStream = connection.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(inputStream));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        builder.append(line);
                    }
                    showUrlData(builder.toString());
                }catch (MalformedURLException e){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),"请输入正确的网址",Toast.LENGTH_SHORT).show();
                        }
                    });
                    e.printStackTrace();
                }catch (IOException e) {
                    e.printStackTrace();
                }finally {
                        if (reader!=null){
                            try {
                                reader.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        if (inputStream!=null){
                            try {
                                inputStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                }
            }
        });
        thread.start();
    }

    /**
     * 更新解析的数据到UI
     * @param builder 解析完成的数据
     */
    private void showUrlData(final String builder) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                reUrlData.setText(builder);
            }
        });
    }
}
